package org.zpmis.api.business;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zpmis.common.base.AdminLoginUser;
import org.zpmis.common.base.BaseWebService;
import org.zpmis.common.constant.UserConstants;
import org.zpmis.common.exception.BusinessException;
import org.zpmis.common.result.ResultCode;
import org.zpmis.common.utils.RedisUtil;
import org.zpmis.domain.org.service.SysUserOrgRelationService;
import org.zpmis.domain.role.model.SysUserRoleRelation;
import org.zpmis.domain.role.service.SysUserRoleRelationService;
import org.zpmis.domain.user.enums.SysUserEnum;
import org.zpmis.domain.user.model.Employee;
import org.zpmis.domain.user.model.SysUser;
import org.zpmis.domain.user.qo.AddSysUserQo;
import org.zpmis.domain.user.qo.EditSysUserQo;
import org.zpmis.domain.user.qo.ResetUserPwdQo;
import org.zpmis.domain.user.qo.SysUserListQo;
import org.zpmis.domain.user.service.EmployeeService;
import org.zpmis.domain.user.service.SysUserService;
import org.zpmis.domain.user.vo.AllSysUserVo;
import org.zpmis.domain.user.vo.SysUserListVo;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created with CodeGenerator
 * Description:
 * @author  Yang
 * Date: 2021-5-31
 * Time: 13:55:42
 */
@Service
@Slf4j
public class SysUserWebService extends BaseWebService {
     @Reference
     private SysUserService sysUserService;

     @Reference
     private EmployeeService employeeService;

     @Reference
     private SysUserOrgRelationService sysUserOrgRelationService;

     @Reference
     private SysUserRoleRelationService sysUserRoleRelationService;


     /**
      * 查询系统所有正常状态的用户信息
      * @return
      */
     public List<AllSysUserVo> allSysUser() throws Exception{
          Condition condition = new Condition(SysUser.class);
          condition.createCriteria()
                  .andEqualTo("isDeleted",0)
                  .andEqualTo("enabled",true)
                  .andEqualTo("accountNonExpired",true)
                  .andEqualTo("accountNonLocked",true)
                  .andEqualTo("credentialsNonExpired",true);
          List<SysUser> sysUserList = sysUserService.findByCondition(condition);
          List<AllSysUserVo> resultList = sysUserList.stream().map(AllSysUserVo::new).collect(Collectors.toList());
          return resultList;
     }

     /**
      * 查询系统所有正常状态的用户信息 显示用户对应的员工姓名
      * 20210908 gf
      * @return
      * @throws Exception
      */
     public List<AllSysUserVo> allSysUserShowEmployee() throws Exception{
          Condition condition = new Condition(SysUser.class);
          condition.createCriteria()
                  .andEqualTo("isDeleted",0)
                  .andEqualTo("enabled",true)
                  .andEqualTo("accountNonExpired",true)
                  .andEqualTo("accountNonLocked",true)
                  .andEqualTo("credentialsNonExpired",true);
          List<SysUser> sysUserList = sysUserService.findByCondition(condition);
          List<AllSysUserVo> resultList;

          if (sysUserList !=null && sysUserList.size() >0){
               //获取用户对应的员工信息
               Condition empCondition = new Condition(Employee.class);
               empCondition.createCriteria()
                       .andIn("sysUid",sysUserList.stream().map(c->c.getId()).collect(Collectors.toList()));
              List<Employee> employeeList =  employeeService.findByCondition(empCondition);
              //员工姓名替换用户名
              if (employeeList != null && employeeList.size() >0){
                   resultList = new  ArrayList<AllSysUserVo>();
                   sysUserList.parallelStream().forEach(u-> {
                        Optional<Employee> employeeOptional = employeeList.stream().filter(e -> e.getSysUid().equals(u.getId())).findFirst();
                        if (employeeOptional.isPresent() && employeeOptional.get() != null) {
                            resultList.add(new AllSysUserVo(u.getId(),employeeOptional.get().getName()));
                        }else {
                             resultList.add(new AllSysUserVo(u.getId(),u.getUserName()));
                        }
                           }
                   );
              }else{
                   resultList = sysUserList.stream().map(AllSysUserVo::new).collect(Collectors.toList());
              }
          }else {
               resultList = sysUserList.stream().map(AllSysUserVo::new).collect(Collectors.toList());
          }

          return resultList;
     }
     /**
      * 新增用户
      * @param addSysUserQo
      * @throws BusinessException
      * @throws Exception
      */
     @Transactional
     public void addSysUser(AddSysUserQo addSysUserQo) throws BusinessException,Exception{
          //获取当前登录用户
          AdminLoginUser adminLoginUser = super.getAdminLoginUser();
          if(adminLoginUser == null){
               throw new BusinessException(ResultCode.USER_NOT_LOGIN);
          }
          SysUser user =sysUserService.findBy("userName",addSysUserQo.getUserName());
          if(user != null && !user.getIsDeleted()){
               throw new BusinessException(ResultCode.USER_ACCOUNT_ALREADY_EXIST);
          }
          SysUser sysUser = SysUser.builder()
                  .userName(addSysUserQo.getUserName())
                  .password(new BCryptPasswordEncoder().encode(addSysUserQo.getPassword()))
                  .createTime(Instant.now().toEpochMilli())
                  .updateTime(Instant.now().toEpochMilli())
                  .createUser(adminLoginUser.getId()).build();
          //新增用户信息
          sysUserService.save(sysUser);
          //用户角色中间表
          List<Long> roleIds = addSysUserQo.getRoleIds();
          if (roleIds != null && !roleIds.isEmpty()) {
               List<SysUserRoleRelation> roleRelations = new ArrayList<SysUserRoleRelation>();
               for (int i = 0; i < roleIds.size(); i++) {
                    SysUserRoleRelation roleRelation = new SysUserRoleRelation();
                    roleRelation.setUserId(sysUser.getId());
                    roleRelation.setRoleId(roleIds.get(i));
                    roleRelations.add(roleRelation);
               }
               sysUserRoleRelationService.save(roleRelations);
          }
     }

     /**
      * 修改用户
      * @param editSysUserQo
      */
     @Transactional
     public void editSysUser(EditSysUserQo editSysUserQo) throws BusinessException,Exception{
          Long sysUserId = editSysUserQo.getId();
          SysUser sysUser = sysUserService.findById(sysUserId);
          if(sysUser == null){
               throw new BusinessException(ResultCode.DATA_NOT_FOUND);
          }
          //获取当前登录用户
          AdminLoginUser adminLoginUser = super.getAdminLoginUser();
          if(adminLoginUser == null){
               throw new BusinessException(ResultCode.USER_NOT_LOGIN);
          }
          //修改用户信息
          sysUserService.update(SysUser.builder()
                  .id(editSysUserQo.getId())
                  .updateUser(getAdminLoginUser().getId())
                  .updateTime(Instant.now().toEpochMilli()).build());
          //删除该用户角色中间表数据
          //sysUserRoleRelationService.deleteRoleRelationsByUserId(editSysUserQo.getId());
          //根据用户id 查询现有用户角色关联表的集合
          Map<String, Object> param = new HashMap<>();
          param.put("userId",sysUserId);
          List<SysUserRoleRelation> userRoleRelations = sysUserRoleRelationService.findByConditionMap(param);
          if(!userRoleRelations.isEmpty()){
               //删除查询到的该角色之前关联的用户关联集合关系
               String userRoleIds = userRoleRelations.stream().map(sysUserRoleRelation -> sysUserRoleRelation.getId().toString()).collect(Collectors.joining(","));
               sysUserRoleRelationService.deleteByIds(userRoleIds);
          }
          //用户角色中间表
          List<Long> roleIds = editSysUserQo.getRoleIds();
          if (roleIds != null && !roleIds.isEmpty()) {
               List<SysUserRoleRelation> roleRelations = new ArrayList<SysUserRoleRelation>();
               for (int i = 0; i < roleIds.size(); i++) {
                    SysUserRoleRelation roleRelation = new SysUserRoleRelation();
                    roleRelation.setUserId(editSysUserQo.getId());
                    roleRelation.setRoleId(roleIds.get(i));
                    roleRelations.add(roleRelation);
               }
               sysUserRoleRelationService.save(roleRelations);
          }
          //让这个用户强制退出重新登录
          super.userIdLogout(Arrays.asList(sysUserId));
     }

     /**
      * 修改密码
      * @param resetUserPwdQo
      */
     public void resetUserPwd(ResetUserPwdQo resetUserPwdQo) throws BusinessException,Exception{

          Long sysUserId = resetUserPwdQo.getId();
          SysUser sysUser = sysUserService.findById(sysUserId);
          if(sysUser == null){
               throw new BusinessException(ResultCode.DATA_NOT_FOUND);
          }
          //获取当前登录用户
          AdminLoginUser adminLoginUser = super.getAdminLoginUser();
          if(adminLoginUser == null){
               throw new BusinessException(ResultCode.USER_NOT_LOGIN);
          }
          //修改密码
          sysUserService.update(SysUser.builder()
                  .id(resetUserPwdQo.getId())
                  .password(new BCryptPasswordEncoder().encode(resetUserPwdQo.getPassword()))
                  .updateTime(Instant.now().toEpochMilli())
                  .updateUser(adminLoginUser.getId()).build());
     }

     /**
      * 删除用户
      * @param id
      */
     public void deleteSysUser(Long id) {
          SysUser sysUser = sysUserService.findById(id);
          if(sysUser == null){
               throw new BusinessException(ResultCode.DATA_NOT_FOUND);
          }
          //删除用户
          sysUserService.update(SysUser.builder()
                  .id(id)
                  .isDeleted(true)
                  .updateTime(Instant.now().toEpochMilli()).build());
     }

     public PageInfo sysUserList(SysUserListQo sysUserListQo) throws Exception{
          String userName = sysUserListQo.getUserName();
          Condition condition = new Condition(SysUser.class);
          Example.Criteria criteria = condition.createCriteria();
          if(StringUtils.isNotBlank(userName)){
               criteria.andLike("userName","%"+userName+"%");
          }
          PageHelper.startPage(sysUserListQo.getPageNum(),sysUserListQo.getPageSize());
          List<SysUser> userList = sysUserService.findByCondition(condition);
          PageInfo pageInfo = new PageInfo<>(userList);
          //设置自定义返回对象
          List<SysUserListVo> resultList = userList.stream().map(SysUserListVo::new).collect(Collectors.toList());
          Map<String, Object> param = new HashMap<>();
          //用户拥有的角色id
          for (SysUserListVo userListVo : resultList) {
               param.put("userId",userListVo.getId());
               List<SysUserRoleRelation> userRoleRelationList = sysUserRoleRelationService.findByConditionMap(param);
               String userRoleRelationIds = userRoleRelationList.stream().map(userRoleRelation -> userRoleRelation.getRoleId().toString()).collect(Collectors.joining(","));
               userListVo.setRoleIds(userRoleRelationIds);
          }
          pageInfo.setList(resultList);
          return pageInfo;
     }

}
